/**
 * 
 */
package common.util;

/**
 * @author doudou
 * @version 0
 *
 */

import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.sql.Time;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Dictionary;

import common.util.enums.IntEnum;
import common.util.enums.StringEnum;
import common.util.exception.IllegalConversionException;
import common.util.exception.InvalidDateException;


// Referenced classes of package com.kingdee.util:
//            IllegalConversionException, InvalidDateException, Uuid, StringUtils, 
//            DateTimeUtils

public class TypeConversionUtils
{

    public TypeConversionUtils()
    {
    }

    public static String objToString(Object obj)
    {
        if(obj == null)
            return null;
        if(obj instanceof String)
            return (String)obj;
        if(obj instanceof StringEnum)
            return ((StringEnum)obj).getValue();
        else
            return obj.toString();
    }

    public static BigDecimal objToBigDecimal(Object obj)
        throws IllegalConversionException
    {
        if(obj == null)
            return null;
        if((obj instanceof String) && StringUtils.isEmpty((String)obj))
            return null;
        if(obj instanceof BigDecimal)
            return (BigDecimal)obj;
        try
        {
            if(obj instanceof Double)
                return new BigDecimal(((Double)obj).doubleValue());
        }
        catch(NumberFormatException ex)
        {
            throw new IllegalConversionException("NumberFormatException");
        }
        return new BigDecimal(obj.toString());
    }

    public static BigDecimal objToBigDecimal(Object obj, int scale)
        throws IllegalConversionException
    {
        if(obj == null)
            return null;
        if((obj instanceof String) && StringUtils.isEmpty((String)obj))
            return null;
        BigDecimal bigdecimal;
        if(obj instanceof BigDecimal)
        {
            bigdecimal = (BigDecimal)obj;
            obj = bigdecimal.setScale(scale, 6);
            return (BigDecimal)obj;
        }
        try
        {
            if(obj instanceof Integer)
            {
                bigdecimal = new BigDecimal(((Integer)obj).intValue());
                return bigdecimal.setScale(scale, 6);
            }
        }
        catch(NumberFormatException _ex)
        {
            throw new IllegalConversionException("NumberFormatException");
        }
        if(obj instanceof Float)
        {
            bigdecimal = new BigDecimal(((Float)obj).doubleValue());
            return bigdecimal.setScale(scale, 6);
        }
        if(obj instanceof Double)
        {
            bigdecimal = new BigDecimal(((Double)obj).doubleValue());
            return bigdecimal.setScale(scale, 6);
        }
        if(obj instanceof String)
        {
            bigdecimal = new BigDecimal((String)obj);
            return bigdecimal.setScale(scale, 6);
        }
        bigdecimal = new BigDecimal(obj.toString());
        return bigdecimal.setScale(scale, 6);
    }

    public static boolean objToBoolean(Object obj)
        throws IllegalConversionException
    {
        if(obj == null)
            return false;
        if(obj instanceof Boolean)
            return ((Boolean)obj).booleanValue();
        String s = obj.toString();
        if(s.equalsIgnoreCase("true"))
            return true;
        if(s.equalsIgnoreCase("yes"))
            return true;
        if(s.equals("1"))
            return true;
        if(s.equalsIgnoreCase("false"))
            return false;
        if(s.equalsIgnoreCase("no"))
            return false;
        if(s.equals("0"))
            return false;
        try
        {
            return Boolean.valueOf(obj.toString()).booleanValue();
        }
        catch(Exception _ex)
        {
            throw new IllegalConversionException("Illegal conversion");
        }
    }

    public static byte objToByte(Object obj)
        throws IllegalConversionException
    {
        if(obj instanceof Byte)
            return ((Byte)obj).byteValue();
        else
            return (byte)objToInt(obj);
    }

    public static short objToShort(Object obj)
        throws IllegalConversionException
    {
        if(obj instanceof Short)
            return ((Short)obj).shortValue();
        else
            return (short)objToInt(obj);
    }

    public static int objToInt(Object obj)
        throws IllegalConversionException
    {
        if(obj == null)
            return 0;
        if(obj instanceof Integer)
            return ((Integer)obj).intValue();
        if(obj instanceof Long)
            return ((Long)obj).intValue();
        if(obj instanceof Float)
            return ((Float)obj).intValue();
        if(obj instanceof Double)
            return ((Double)obj).intValue();
        if(obj instanceof BigDecimal)
            return ((BigDecimal)obj).intValue();
        if(obj instanceof Boolean)
            return ((Boolean)obj).booleanValue() ? 1 : 0;
        if(obj instanceof IntEnum)
            return ((IntEnum)obj).getValue();
        try
        {
            return Integer.valueOf(obj.toString()).intValue();
        }
        catch(Exception _ex)
        {
            throw new IllegalConversionException("Illegal conversion");
        }
    }

    public static long objToLong(Object obj)
        throws IllegalConversionException
    {
        if(obj == null)
            return 0L;
        if(obj instanceof Integer)
            return ((Integer)obj).longValue();
        if(obj instanceof Long)
            return ((Long)obj).longValue();
        if(obj instanceof Float)
            return ((Float)obj).longValue();
        if(obj instanceof Double)
            return ((Double)obj).longValue();
        if(obj instanceof BigDecimal)
            return ((BigDecimal)obj).longValue();
        try
        {
            return Long.valueOf(obj.toString()).longValue();
        }
        catch(Exception _ex)
        {
            throw new IllegalConversionException("Illegal conversion");
        }
    }

    public static float objToFloat(Object obj)
        throws IllegalConversionException
    {
        if(obj == null)
            return 0.0F;
        if(obj instanceof Integer)
            return ((Integer)obj).floatValue();
        if(obj instanceof Long)
            return ((Long)obj).floatValue();
        if(obj instanceof Float)
            return ((Float)obj).floatValue();
        if(obj instanceof Double)
            return ((Double)obj).floatValue();
        if(obj instanceof BigDecimal)
            return ((BigDecimal)obj).floatValue();
        try
        {
            return Float.valueOf(obj.toString()).floatValue();
        }
        catch(Exception _ex)
        {
            throw new IllegalConversionException("Illegal conversion");
        }
    }

    public static double objToDouble(Object obj)
        throws IllegalConversionException
    {
        if(obj == null)
            return 0.0D;
        if(obj instanceof Integer)
            return ((Integer)obj).doubleValue();
        if(obj instanceof Long)
            return ((Long)obj).doubleValue();
        if(obj instanceof Float)
            return ((Float)obj).doubleValue();
        if(obj instanceof Double)
            return ((Double)obj).doubleValue();
        if(obj instanceof BigDecimal)
            return ((BigDecimal)obj).doubleValue();
        try
        {
            return Double.valueOf(obj.toString()).doubleValue();
        }
        catch(Exception _ex)
        {
            throw new IllegalConversionException("Illegal conversion");
        }
    }

    public static Time objToTime(Object obj)
        throws InvalidDateException, IllegalConversionException, ParseException
    {
        if(obj == null)
            return null;
        if(obj instanceof Time)
            return (Time)obj;
        Date date;
        DateFormat df;
        String strObj;
        try
        {
            if(obj instanceof Timestamp)
            {
                Timestamp timestamp = (Timestamp)obj;
                return new Time(timestamp.getTime());
            }
        }
        catch(IllegalArgumentException _ex)
        {
            throw new InvalidDateException("Illegal date value - Java Time Objects cannot be earlier than 1/1/70");
        }
        catch(Exception _ex)
        {
            throw new IllegalConversionException("Illegal conversion");
        }
        if(obj instanceof Date)
        {
            date = (Date)obj;
            return new Time(date.getTime());
        }
        df = DateFormat.getTimeInstance();
        strObj = obj.toString();
        return new Time(df.parse(strObj).getTime());
    }

    public static Time string2Time(String time)
        throws IllegalConversionException
    {
        java.sql.Date date = string2Date(time);
        if(date == null)
            return null;
        else
            return new Time(date.getTime());
    }

    public static java.sql.Date string2Date(String str)
        throws IllegalConversionException
    {
        if(StringUtils.isEmpty(str))
            return null;
        str = str.trim().toLowerCase();
        if(str.startsWith("{ts"))
            str = str.substring(3).trim();
        if(str.startsWith("'"))
            str = str.substring(1).trim();
        if(str.endsWith("}"))
            str = str.substring(0, str.length() - 1).trim();
        if(str.endsWith("'"))
            str = str.substring(0, str.length() - 1).trim();
        String dfs = "yyyy-MM-dd";
        if(str.length() > dfs.length())
            dfs = "yyyy-MM-dd HH:mm:ss";
        DateFormat df = new SimpleDateFormat(dfs);
        Date date;
        try
        {
            date = df.parse(str);
        }
        catch(ParseException e)
        {
            throw new IllegalConversionException("parse date error");
        }
        return new java.sql.Date(date.getTime());
    }

    public static Timestamp string2Timestamp(String str)
        throws IllegalConversionException
    {
        java.sql.Date date = string2Date(str);
        if(date == null)
            return null;
        else
            return new Timestamp(date.getTime());
    }

    public static void main(String args[])
    {
        System.out.println(string2Date("{ts'1979-01-01'}"));
    }

    public static java.sql.Date objToDate(Object obj)
        throws InvalidDateException, IllegalConversionException, ParseException
    {
        if(obj == null)
            return null;
        if(obj instanceof java.sql.Date)
            return (java.sql.Date)obj;
        Date date;
        try
        {
            if(obj instanceof Timestamp)
            {
                Timestamp timestamp = (Timestamp)obj;
                return new java.sql.Date(timestamp.getTime());
            }
        }
        catch(IllegalArgumentException _ex)
        {
            throw new InvalidDateException("Illegal date value - Java Date Objects cannot be earlier than 1/1/70");
        }
        catch(Exception _ex)
        {
            throw new IllegalConversionException("Illegal conversion");
        }
        if(obj instanceof Date)
        {
            date = (Date)obj;
            return new java.sql.Date(date.getTime());
        }
        return new java.sql.Date(DateTimeUtils.parseDate(obj.toString()).getTime());
    }

    public static Date objToUtilDate(Object obj)
        throws InvalidDateException, IllegalConversionException, ParseException
    {
        if(obj == null)
            return null;
        java.sql.Date date;
        Timestamp timestamp;
        String strObj;
        try
        {
            if(obj instanceof Time)
            {
                Time time = (Time)obj;
                return new Date(time.getTime());
            }
        }
        catch(IllegalArgumentException _ex)
        {
            throw new InvalidDateException("Illegal java.util.Date value - java.util.Date Objects cannot be earlier than 1/1/70");
        }
        catch(Exception _ex)
        {
            throw new IllegalConversionException("Illegal conversion");
        }
        if(obj instanceof java.sql.Date)
        {
            date = (java.sql.Date)obj;
            return new Date(date.getTime());
        }
        if(obj instanceof Timestamp)
        {
            timestamp = (Timestamp)obj;
            return new Date(timestamp.getTime());
        }
        if(obj instanceof Date)
            return (Date)obj;
        strObj = obj.toString();
        return DateTimeUtils.parseDate(strObj);
    }

    public static Timestamp objToTimestamp(Object obj)
        throws InvalidDateException, IllegalConversionException, ParseException
    {
        if(obj == null)
            return null;
        if(obj instanceof Timestamp)
            return (Timestamp)obj;
        java.sql.Date date;
        Date dt;
        String strObj;
        try
        {
            if(obj instanceof Time)
            {
                Time time = (Time)obj;
                return new Timestamp(time.getTime());
            }
        }
        catch(IllegalArgumentException _ex)
        {
            throw new InvalidDateException("Illegal Timestamp value - Java Timestamp Objects cannot be earlier than 1/1/70");
        }
        catch(Exception _ex)
        {
            throw new IllegalConversionException("Illegal conversion");
        }
        if(obj instanceof java.sql.Date)
        {
            date = (java.sql.Date)obj;
            return new Timestamp(date.getTime());
        }
        if(obj instanceof Date)
        {
            dt = (Date)obj;
            return new Timestamp(dt.getTime());
        }
        strObj = obj.toString();
        return new Timestamp(DateTimeUtils.parseDate(strObj).getTime());
    }

    public static byte[] objToBytes(Object obj)
        throws IllegalConversionException
    {
        if(obj == null)
            return null;
        if(obj instanceof byte[])
            return (byte[])obj;
        if(obj instanceof Long)
        {
            long val = ((Long)obj).longValue();
            byte b[] = new byte[8];
            b[7] = (byte)(int)(val >>> 0);
            b[6] = (byte)(int)(val >>> 8);
            b[5] = (byte)(int)(val >>> 16);
            b[4] = (byte)(int)(val >>> 24);
            b[3] = (byte)(int)(val >>> 32);
            b[2] = (byte)(int)(val >>> 40);
            b[1] = (byte)(int)(val >>> 48);
            b[0] = (byte)(int)(val >>> 56);
            return b;
        }
        if(obj instanceof Integer)
        {
            long val = ((Integer)obj).longValue();
            byte b[] = new byte[8];
            b[7] = (byte)(int)(val >>> 0);
            b[6] = (byte)(int)(val >>> 8);
            b[5] = (byte)(int)(val >>> 16);
            b[4] = (byte)(int)(val >>> 24);
            b[3] = (byte)(int)(val >>> 32);
            b[2] = (byte)(int)(val >>> 40);
            b[1] = (byte)(int)(val >>> 48);
            b[0] = (byte)(int)(val >>> 56);
            return b;
        }
        try
        {
            if(obj instanceof String)
            {
                String s = (String)obj;
                return s.getBytes();
            }
        }
        catch(Exception _ex)
        {
            throw new IllegalConversionException("Illegal conversion");
        }
        throw new IllegalConversionException("Illegal conversion");
    }
    
    
    public static Dictionary stringToDictionary(String s, Dictionary dictionary)
    {
        return stringToDictionary(s, dictionary, ',');
    }

    public static Dictionary stringToDictionary(String s, Dictionary dictionary, char ch)
    {
        if(s == null)
            return dictionary;
        String as[] = StringUtils.fastSplit(s, ch);
        for(int i = as.length - 1; i > -1; i--)
        {
            String as1[] = StringUtils.split(as[i], 61);
            dictionary.put(as1[0], as1[1]);
        }

        return dictionary;
    }

    public static int getLongHi(long l)
    {
        return (int)(l >> 32);
    }

    public static int getLongLo(long l)
    {
        return (int)(l & 4294967295L);
    }

    public static long intToLong(int hiWord, int loWord)
    {
        long l = (long)hiWord & 4294967295L;
        l <<= 32;
        return l | (long)loWord & 4294967295L;
    }

    public static long intToLong(int i)
    {
        return (long)i & 4294967295L;
    }

    public static int longToInt(long l)
    {
        return (int)(l & 4294967295L);
    }

    public static Object stringToObject(int sqlType, String str)
        throws IllegalConversionException
    {
        if(str == null)
            return null;
        switch(sqlType)
        {
        case -7: 
            return Boolean.valueOf(objToBoolean(str));

        case -6: 
        case 4: // '\004'
        case 5: // '\005'
            return new Integer(objToInt(str));

        case -5: 
            return new Long(objToLong(str));

        case 6: // '\006'
        case 7: // '\007'
        case 8: // '\b'
            return new Double(objToDouble(str));

        case 2: // '\002'
        case 3: // '\003'
            return objToBigDecimal(str);

        case -1: 
        case 1: // '\001'
        case 12: // '\f'
            return str;

        case -3: 
        case -2: 
        case 2004: 
            return objToBytes(str);

        case 91: // '['
            return string2Date(str);

        case 92: // '\\'
            return string2Time(str);

        case 93: // ']'
            return string2Timestamp(str);

        case 2005: 
            return str;
        }
        throw new IllegalConversionException("sqlType " + sqlType + " not supported.");
    }

    public static String numberToPlainString(Object obj)
    {
        if(obj == null)
            return null;
        if(!(obj instanceof Number))
            throw new IllegalConversionException();
        BigDecimal dec = objToBigDecimal(obj);
        synchronized(common.util.TypeConversionUtils.class)
        {
            if(useJdk15Method == null)
            {
                useJdk15Method = Boolean.TRUE;
                try
                {
                    (java.math.BigDecimal.class).getMethod("toPlainString", null);
                }
                catch(Exception e)
                {
                    useJdk15Method = Boolean.FALSE;
                }
            }
        }
        if(useJdk15Method.booleanValue())
            try
            {
                Method toPlainString = (java.math.BigDecimal.class).getMethod("toPlainString", null);
                return (String)toPlainString.invoke(dec, null);
            }
            catch(Exception e) { }
        return dec.toString();
    }

    private static Boolean useJdk15Method = null;

}


